#include "iostream"
#include <fstream>
#include "protobuf.pb/contacts.pb.h"
#include "protobuf.pb/Phone.pb.h"


//编译器提供了指令可以允许你转换为文本格式
//  protoc --proto_path=./protobuf/protobuf.pb --decode=Ctct.Contacts contacts.proto Phone.proto < ./protobuf/Contacts.bin



int main()
{
    //验证版本，
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    std::fstream fs("Contacts.bin",std::ios::binary | std::ios::app | std::ios::out|std::ios::in);
    if(!fs.is_open())
    {
        std::cerr<<"文件打开失败\n";
    }
    Ctct::Contacts ctct;
    if(!ctct.ParseFromIstream(&fs))
    {
        std::cout<<"反序列化失败\n";
    }
    for(int i = 0;i<ctct.personinfo_size();i++)
    {
        std::cout<<ctct.personinfo(i).age()<<" ";
        std::cout<<ctct.personinfo(i).name()<< " ";
        for(int j  =0;j<ctct.personinfo(i).phonenum_size();j++)
        {
            //enum形会提供如下获取名字的方法
            std::cout<<ctct.personinfo(i).phonenum(j).PhoneType_Name(ctct.personinfo(i).phonenum(j).pdtype())<<std::endl;
            std::cout<< ctct.personinfo(i).phonenum(j).GetTypeName()<<std::endl;//每一个message类都会提供获取其类名字的方法
            std::cout<<ctct.personinfo(i).phonenum(j).number()<<std::endl;
        }
        //对any类型，提供了判断其是否存储了数据的函数,并且提供了判断是否是某类型的函数 
        if(ctct.personinfo(i).has_addr_data() && ctct.personinfo(i).addr_data().Is<Ctct::Addr>())
        {
            Ctct::Addr addr;
            ctct.personinfo(i).addr_data().UnpackTo(&addr);//有返回值
            std::cout<<addr.home_addr()<<" "<<addr.word_addr()<<std::endl;
        }
        std::cout<<"学历：";
        switch(ctct.personinfo(i).educational_background_case())
        {
            
            case Ctct::PeopleInfo::EducationalBackgroundCase::kCollege:
            {
                std::cout<<"College\n";
                break;
            }
            case Ctct::PeopleInfo::EducationalBackgroundCase::kJunior:
            {
                std::cout<<"中学\n";
                break;
            }
            case Ctct::PeopleInfo::EducationalBackgroundCase::kMaster:
            {
                std::cout<<"硕士\n";
                break;
            }
        }
        for(const auto& str:ctct.personinfo(i).remark())
        {
            std::cout<<"备注："<<str.first<<":"<<str.second<<"\n";
        }
    }
    fs.close();

    google::protobuf::ShutdownProtobufLibrary();


    return 0;
}